<!DOCTYPE html>
<html>
<body>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script type="text/javascript">

// Interval prepared to wait until deciding if 'abort' has been delivered (or not.)
var TIME_DELAY_ABORT_DELIVERY = 200;

test(function()
{
    var xhr = new XMLHttpRequest;
    xhr.onreadystatechange = this.step_func(function() {
        assert_unreached("Received readystatechange event unexpectedly: readyState=" + xhr.readyState)
    });
    xhr.onabort = this.step_func(function () {
        assert_unreached("Unexpected 'abort' event in state UNSENT.");
    });
    xhr.abort();
    assert_equals(xhr.readyState, xhr.UNSENT, "xhr.readyState after abort() call");
}, "Test onreadystatechange + onabort invocation when abort()-ed in UNSENT state.");

test(function()
{
    var xhr = new XMLHttpRequest;
    var seenStates = [];
    xhr.onreadystatechange = this.step_func(function() {
        seenStates.push(xhr.readyState);

        switch (xhr.readyState) {
        case xhr.OPENED:
            return;

        case xhr.UNSENT:
        case xhr.HEADERS_RECEIVED:
        case xhr.LOADING:
        case xhr.DONE:
        default:
            assert_unreached("Unexpected readyState: " + xhr.readyState);
            return;
        }
    });
    xhr.onabort = this.step_func(function () {
        assert_unreached("Unexpected 'abort' event in state OPENED.");
    });
    xhr.open("GET", "resources/test.ogv", true);
    xhr.abort();
    assert_equals(xhr.readyState, xhr.OPENED, "xhr.readyState after abort() call");
    assert_array_equals(seenStates, [xhr.OPENED]);
}, "Test onreadystatechange + onabort invocation when abort()-ed in OPENED state.");

var abortAfterSendTest = async_test("Test onreadystatechange + onabort invocation when abort()-ed right after calling send().");
abortAfterSendTest.step(function()
{
    var xhr = new XMLHttpRequest;
    var seenStates = [];
    xhr.onreadystatechange = this.step_func(function() {
        seenStates.push(xhr.readyState);

        switch (xhr.readyState) {
        case xhr.OPENED:
        case xhr.DONE:
            return;

        case xhr.UNSENT:
        case xhr.HEADERS_RECEIVED:
        case xhr.LOADING:
        default:
            assert_unreached("Unexpected readyState: " + xhr.readyState);
            return;
        }
    });
    var abortFired = false;
    xhr.onabort = function () {
        abortFired = true;
    };
    xhr.open("GET", "resources/test.ogv", true);
    xhr.send();
    xhr.abort();
    assert_equals(xhr.readyState, xhr.UNSENT, "xhr.readyState after abort() call");
    assert_array_equals(seenStates, [xhr.OPENED, xhr.DONE]);
    setTimeout(abortAfterSendTest.step_func(function () {
        assert_true(abortFired, "Expected 'abort' event to have fired in sent request.");
        abortAfterSendTest.done();
    }), TIME_DELAY_ABORT_DELIVERY);
});

var abortInHeadersReceivedTest = async_test("Test onreadystatechange + onabort invocation when abort()-ed in HEADERS_RECEIVED state.");
abortInHeadersReceivedTest.step(function()
{
    var xhr = new XMLHttpRequest;
    var seenStates = [];
    xhr.onreadystatechange = abortInHeadersReceivedTest.step_func(function() {
        seenStates.push(xhr.readyState);

        switch (xhr.readyState) {
        case xhr.OPENED:
        case xhr.DONE:
            return;

        case xhr.HEADERS_RECEIVED:
            xhr.abort();
            assert_equals(xhr.readyState, xhr.UNSENT, "xhr.readyState after abort() call");
            assert_array_equals(seenStates, [xhr.OPENED, xhr.HEADERS_RECEIVED, xhr.DONE]);
            setTimeout(abortInHeadersReceivedTest.step_func(function() {
                assert_true(abortFired, "Expected 'abort' event to have fired in HEADERS_RECEIVED state.");
                abortInHeadersReceivedTest.done();
            }), TIME_DELAY_ABORT_DELIVERY);
            return;

        case xhr.UNSENT:
        case xhr.LOADING:
        default:
            assert_unreached("Unexpected readyState: " + xhr.readyState)
            return;
        }
    });
    var abortFired = false;
    xhr.onabort = function () {
        abortFired = true;
    };
    xhr.open("GET", "resources/test.ogv", true);
    xhr.send();
});

var abortInLoadingTest = async_test("Test onreadystatechange + onabort invocation when abort()-ed in LOADING state.");
abortInLoadingTest.step(function()
{
    var xhr = new XMLHttpRequest;
    var seenStates = [];
    xhr.onreadystatechange = abortInLoadingTest.step_func(function() {
        seenStates.push(xhr.readyState);

        switch (xhr.readyState) {
        case xhr.OPENED:
        case xhr.HEADERS_RECEIVED:
        case xhr.DONE:
            return;

        case xhr.LOADING:
            xhr.abort();
            assert_equals(xhr.readyState, xhr.UNSENT, "xhr.readyState after abort() call");
            assert_array_equals(seenStates, [xhr.OPENED, xhr.HEADERS_RECEIVED, xhr.LOADING, xhr.DONE]);
            setTimeout(abortInLoadingTest.step_func(function() {
                assert_true(abortFired, "Expected 'abort' event to have fired in LOADING state.");
                abortInLoadingTest.done();
            }), TIME_DELAY_ABORT_DELIVERY);
            return;

        case xhr.UNSENT:
        default:
            assert_unreached("Unexpected readyState: " + xhr.readyState)
            return;
        }
    });
    var abortFired = false;
    xhr.onabort = function () {
        abortFired = true;
    };
    xhr.open("GET", "resources/test.ogv", true);
    xhr.send();
});

var abortInDoneTest = async_test("Test onreadystatechange + onabort invocation when abort()-ed in DONE state.");
abortInDoneTest.step(function()
{
    var xhr = new XMLHttpRequest;
    var seenStates = [];
    xhr.onreadystatechange = abortInDoneTest.step_func(function() {
        seenStates.push(xhr.readyState);

        switch (xhr.readyState) {
        case xhr.OPENED:
        case xhr.HEADERS_RECEIVED:
        case xhr.LOADING:
            return;

        case xhr.DONE:
            xhr.abort();
            assert_equals(xhr.readyState, xhr.UNSENT, "xhr.readyState after abort() call");
            assert_array_equals(seenStates, [xhr.OPENED, xhr.HEADERS_RECEIVED, xhr.LOADING, xhr.DONE]);

            setTimeout(abortInDoneTest.step_func(function() {
                abortInDoneTest.done();
            }), TIME_DELAY_ABORT_DELIVERY);
            return;

        case xhr.UNSENT:
        default:
            assert_unreached("Unexpected readyState: " + xhr.readyState)
            return;
        }
    });
    xhr.onabort = abortInDoneTest.step_func(function () {
        assert_unreached("abort() should not cause the abort event to fire");
    });
    xhr.open("GET", "resources/test.ogv", true);
    xhr.send();
});
</script>
</body>
</html>
